package com.xiangxiao.rpan.storage.cos;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.Bucket;
import com.qcloud.cos.model.CannedAccessControlList;
import com.qcloud.cos.model.CreateBucketRequest;
import com.qcloud.cos.region.Region;
import lombok.Setter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.io.File;
import java.net.URL;

/**
 * @ClassName CosStorageConfig
 * @Auther admin
 * @Email 573768011@qq.com
 * @Date 2024/8/2 17:12
 */
@Setter
@SpringBootConfiguration
@ConfigurationProperties(prefix = "rpan.storage.cos") /** 该注解在多线程环境中能够正常获取配置文件application.yml中的值 */
@ConditionalOnProperty(prefix = "rpan.storage.processor", name = "type", havingValue = "com.xiangxiao.rpan.storage.cos.CosStorageProcessor")
public class CosStorageConfig implements InitializingBean {
  private String secretId;
  private String secretKey;
  private String bucketName;
  private String region;
  private String printUrl;
  private String prePath;

  public static String Tencent_secretId;
  public static String Tencent_secretKey;
  public static String Tencent_bucketName;
  public static String Tencent_region;
  public static String Tencent_printUrl;
  public static String Tencent_path;
  /**
   * COSClient类型的静态变量
   * 注意：请确保程序生命周期内COSClient实例只有一个
   */
  private static COSClient sCosClient;

  private static final String DEFAULT_ROOT_FILE_NAME = "rpan";
  private final static String CHUNKS_FOLDER_NAME = "coschunks";

  /**
   * 实际存放路径前缀
   */
  private static String rootFilePath = System.getProperty("user.home") + File.separator + DEFAULT_ROOT_FILE_NAME;

  /**
   * 临时分片文件存放路径前缀
   */
  private static String chunksPath = rootFilePath + File.separator + CHUNKS_FOLDER_NAME;

  @Override
  public void afterPropertiesSet() throws Exception {
    Tencent_secretId = secretId;
    Tencent_secretKey = secretKey;
    Tencent_bucketName = bucketName;
    Tencent_region = region;
    Tencent_printUrl = printUrl;
    Tencent_path = prePath;
  }

  /**
   * 初始化CosClient实例，在Springboot初始化执行一次，可以保证COSClient实例只有一个
   */
  public static void initCosClient() {
    //----------------------初始化客户端---------------------------
    // 1 初始化用户身份信息（secretId, secretKey）。
    String secretId = Tencent_secretId;
    String secretKey = Tencent_secretKey;
    COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
    // 2 设置 bucket 的地域
    // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
    Region region = new Region(Tencent_region);
    ClientConfig clientConfig = new ClientConfig(region);
    // 这里建议设置使用 https 协议
    // 从 5.6.54 版本开始，默认使用了 https
    clientConfig.setHttpProtocol(HttpProtocol.https);
    // 3 生成 cos 客户端。
    COSClient cosClient = new COSClient(cred, clientConfig);
    // 为COSClient静态变量赋值
    sCosClient = cosClient;
  }

  /**
   * 创建存储桶，如果在 COS控制台中提前创建好了存储桶，并且没有额外创建存储桶的需求，该方法是不必执行的。
   * 注意：这里自动创建了 公有读私有写 的存储桶，如果想要改变，可以将该属性设置为该方法的一个参数
   * @param bucketName 存储桶名称
   */
  public static void createBucket(String bucketName) {
    //-------------------创建存储桶-------------------------
    //存储桶名称，格式：BucketName-APPID
    CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
    // 设置 bucket 的权限为 Private(私有读写)、其他可选有 PublicRead（公有读私有写）、PublicReadWrite（公有读写）
    createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead);
    try {
      Bucket bucketResult = sCosClient.createBucket(createBucketRequest);
    } catch (CosServiceException serverException) {
      serverException.printStackTrace();
    } catch (CosClientException clientException) {
      clientException.printStackTrace();
    }
  }

  /**
   * 获取COSClient实例
   * @return cosclient实例
   */
  public static COSClient getCosClient () {
    return sCosClient;
  }

  public static String getChunksPath() {
    return chunksPath;
  }

  /**
   * 根据 bucketName 和 key 获取 URL 对象
   * @param bucketName 存储桶名称
   * @param key 文件路径及文件内容的组合
   * @return URL 对象
   */
  public static URL getURL(String bucketName, String key) {
    URL url = sCosClient.getObjectUrl(bucketName, key);
    return url;
  }

  /**
   * 重写方法，根据 key 获取 URL 对象
   * @param key 文件路径及文件内容的组合
   * @return URL 对象
   */
  public static URL getURL(String key) {
    return getURL(Tencent_bucketName, key);
  }

  /**
   * 关闭 COSClient 实例，在 springboot 销毁时调用
   */
  public static void shutdownClient() {
    // 关闭客户端(关闭后台线程)
    sCosClient.shutdown();
  }

}
